﻿using AvalonDock.Layout;
using AvalonDock.Layout.Serialization;
using Microsoft.Win32;
using System.Globalization;
using System.IO;
using System.Windows;
using System.Windows.Interop;
using System.Windows.Threading;
using VM.CameraSet;
using VM.Common.Enums;
using VM.Common.EventMgrLib;
using VM.Common.Helper;
using VM.Dialogs.Views;
using VM.Events;
using VM.Start.Common.Helper;
using VM.Start.Common.RightControl;
using VM.Start.Dialogs.Views;
using VM.Start.Localization;
using VM.Start.Models;
using VM.Start.PersistentData;
using VM.Start.Services;
using VM.Start.Views;
using VM.Start.Views.Dock;
using WPFLocalizeExtension.Engine;

namespace VM.Start
{
    public class MainViewModel : NotifyPropertyBase
    {
        #region Singleton

        private static readonly MainViewModel _instance = new MainViewModel();

        private MainViewModel()
        {
            //EventMgr.Ins.GetEvent<CurrentUserChangedEvent>().Subscribe(user => OnUserChanged(user));
        }

        public static MainViewModel Ins
        {
            get { return _instance; }
        }

        #endregion
        #region 属性
        /// <summary>
        /// 主页面
        /// </summary>
        public MainView mainView { get; set; }
        /// <summary>
        /// 当前时间
        /// </summary>
        private string _CurrentTime;
        public string CurrentTime
        {
            get { return _CurrentTime; }
            set { Set(ref _CurrentTime, value); }
        }

        /// <summary>
        /// 当前解决方案
        /// </summary>
        private string _CurrentSolution;
        public string CurrentSolution
        {
            get { return _CurrentSolution; }
            set { Set(ref _CurrentSolution, value); }
        }

        /// <summary>
        /// 视图是否选中
        /// </summary>
        private bool _IsCheckedVision = true;
        public bool IsCheckedVision
        {
            get { return _IsCheckedVision; }
            set
            {
                _IsCheckedVision = value;
                this.RaisePropertyChanged();
                VisibleOrHideView(_IsCheckedVision, "Vision", "LayoutDocument");
            }
        }

        public static LayoutDocument LayoutDocument_Vision = new LayoutDocument
        {
            Title = Resource.Dock_Vision,
            CanClose = false,
            ContentId = "Vision",
            Content = new VisionView()
        };

        #endregion
        #region 指令

        private CommandBase _LoadedCommand;
        public CommandBase LoadedCommand
        {
            get
            {
                if (_LoadedCommand == null)
                {
                    _LoadedCommand = new CommandBase(
                        (obj) =>
                        {
                            //【1】当前时间
                            DispatcherTimer timer = new DispatcherTimer();
                            timer.Interval = TimeSpan.FromMilliseconds(100);
                            timer.Tick += (sender, e) =>
                            {
                                Timer100ms_Tick(sender, e);
                            };
                            timer.Start();

                            // 在命令执行后需要确保清理定时器
                            // 在某些情况下，确保定时器停止和销毁
                            Action cleanup = () =>
                            {
                                if (timer != null)
                                {
                                    timer.Stop();
                                    timer.Tick -= (sender, e) => Timer100ms_Tick(sender, e);  // 注销 Tick 事件
                                    timer = null;
                                }
                            };

                            //// 注册快捷键
                            //RegisterHotKey();
                            //UnregisterHotKey();
                            // 初始化UI
                            InitUI();
                            // 加载配方
                            if (SystemConfig.Ins.SolutionAutoLoad)
                            {
                                OpenSolution(SystemConfig.Ins.SolutionPathText);
                                if (SystemConfig.Ins.SolutionAutoRun)
                                {
                                    //Solution.Ins.QuickMode = true;
                                    //MainView.Ins.btnQuickMode.Foreground = Brushes.Lime;
                                    Solution.Ins.StartRun();
                                }
                            }

                            // 在命令执行完成时清理资源
                            cleanup();
                        }
                    );
                }
                return _LoadedCommand;
            }
        }

        private CommandBase _ClosingCommand;
        public CommandBase ClosingCommand
        {
            get
            {
                if (_ClosingCommand == null)
                {
                    _ClosingCommand = new CommandBase(
                        async (obj) =>
                        {
                            foreach (var item in Solution.Ins.ProjectList)
                            {
                                if (item.GetThreadStatus())
                                {
                                    MessageView.Ins.MessageBoxShow("程序运行状态禁止关闭软件！", eMsgType.Warn);
                                    (obj as System.ComponentModel.CancelEventArgs).Cancel = true;
                                    return;
                                }
                            }
                            var messageView = MessageView.Ins;
                            messageView.MessageBoxShow(
                                Resource.QuitSystem,
                                eMsgType.Warn,
                                MessageBoxButton.OKCancel
                            );
                            if (messageView.DialogResult == false)
                            {
                                (obj as System.ComponentModel.CancelEventArgs).Cancel = true;
                            }
                            else
                            {
                                EventMgr.Ins.GetEvent<SoftwareExitEvent>().Publish();
                                //await Task.Delay( 1000 );
                                NLog.LogManager.Shutdown();
                                Environment.Exit(0);
                                //CommonMethods.Exit();
                            }
                        }
                    );
                }
                return _ClosingCommand;
            }
        }

        private CommandBase _LoadLayoutCommand;
        public CommandBase LoadLayoutCommand
        {
            get
            {
                if (_LoadLayoutCommand == null)
                {
                    _LoadLayoutCommand = new CommandBase(
                        (obj) =>
                        {
                            var layoutSerializer = new XmlLayoutSerializer(
                                DockView.Ins.dockManager
                            );
                            layoutSerializer.Deserialize(FilePaths.DockLayout);
                        },
                        (O) => File.Exists(FilePaths.DockLayout)
                    );
                }
                return _LoadLayoutCommand;
            }
        }

        private CommandBase _LoadDefaultLayoutCommand;
        public CommandBase LoadDefaultLayoutCommand
        {
            get
            {
                if (_LoadDefaultLayoutCommand == null)
                {
                    _LoadDefaultLayoutCommand = new CommandBase(
                        (obj) =>
                        {
                            var layoutSerializer = new XmlLayoutSerializer(
                                DockView.Ins.dockManager
                            );
                            layoutSerializer.Deserialize(FilePaths.DefaultDockLayout);
                        },
                        (O) => File.Exists(FilePaths.DefaultDockLayout)
                    );
                }
                return _LoadDefaultLayoutCommand;
            }
        }

        [Newtonsoft.Json.JsonIgnore]
        private CommandBase _NavOperateCommand;
        [Newtonsoft.Json.JsonIgnore]
        public CommandBase NavOperateCommand
        {
            get
            {
                if (_NavOperateCommand == null)
                {
                    _NavOperateCommand = new CommandBase(async (obj) =>
                    {
                        switch (obj)
                        {
                            case "NewSolution": //新建解决方案
                                Solution.Ins.CreateSolution();
                                break;
                            case "Open": //打开
                                await OpenSolutionAsync();
                                break;
                            case "Save": //保存
                                if (!CanSaveSolution())
                                    return;

                                if (CurrentSolution != null && File.Exists(CurrentSolution))
                                {
                                    SerializeHelp.BinSerializeAndSaveFile(
                                        Solution.Ins,
                                        CurrentSolution
                                    );
                                }
                                else
                                {
                                    string? filePath = ShowSaveFileDialog("保存解决方案", "Test.vm", "解决方案|*.vm");
                                    if (!string.IsNullOrEmpty(filePath))
                                    {
                                        CurrentSolution = filePath;
                                        SerializeHelp.BinSerializeAndSaveFile(Solution.Ins, CurrentSolution);
                                    }
                                }
                                //Logger.AddLog("解决方案保存成功！", eMsgType.Success, isDispGrowl: true);
                                break;
                            case "SaveAs": //另保存
                                if (!CanSaveSolution())
                                    return;

                                string? savePath = ShowSaveFileDialog("另存为", "Test.vm", "解决方案|*.vm");
                                if (!string.IsNullOrEmpty(savePath))
                                {
                                    CurrentSolution = savePath;
                                    SerializeHelp.BinSerializeAndSaveFile(Solution.Ins, CurrentSolution);
                                }
                                break;
                            case "CameraSet": //相机设置
                                CameraSetView.Ins.ShowWindow();
                                break;
                            case "CommunicationSet": //通讯设置
                                CommunicationSetView.Ins.ShowDialog();
                                break;
                            case "English":
                                LocalizeDictionary.Instance.Culture = new CultureInfo("en");
                                break;
                            case "Chinese":
                                LocalizeDictionary.Instance.Culture = new CultureInfo("zh");
                                break;
                            default:
                                break;
                        }
                    }
                    );
                }
                return _NavOperateCommand;
            }
        }

        private CommandBase _HelpDocumentCommand;
        public CommandBase HelpDocumentCommand
        {
            get
            {
                if (_HelpDocumentCommand == null)
                {
                    _HelpDocumentCommand = new CommandBase(
                        (obj) =>
                        {
                            string HelpDecomentFullName =
                                $"{FilePaths.HelpDecomentPath}{SystemConfig.Ins.ProjectName}Help_{SystemConfig.Ins.CurrentCultureName}.chm";
                            if (!File.Exists(HelpDecomentFullName))
                            {
                                MessageView.Ins.MessageBoxShow(
                                    Resource.HelpDecomentNotFind,
                                    eMsgType.Warn
                                );
                                return;
                            }
                            System.Diagnostics.Process process = new System.Diagnostics.Process();
                            process.StartInfo.FileName = HelpDecomentFullName;
                            process.StartInfo.Verb = "Open";
                            process.StartInfo.CreateNoWindow = true;
                            process.StartInfo.WindowStyle = System
                                .Diagnostics
                                .ProcessWindowStyle
                                .Normal;
                            process.Start();
                        }
                    );
                }
                return _HelpDocumentCommand;
            }
        }
        #endregion
        #region  方法
        private void Timer100ms_Tick(object sender, EventArgs e)
        {
            CurrentTime = DateTime.Now.ToString();
        }

        /// <summary>
        /// 初始化UI
        /// </summary>
        private void InitUI()
        {
            //加载布局
            if (SystemConfig.Ins.AutoLoadLayout)
            {
                LoadLayoutCommand.Execute(1);
            }

            //图像视图显示
            IsCheckedVision = true;
        }

        /// <summary>
        /// 可视化试图
        /// </summary>
        /// <param name="isChecked"></param>
        /// <param name="contentId"></param>
        /// <param name="typeOfLayout"></param>
        public void VisibleOrHideView(bool isChecked, string contentId, string typeOfLayout = "LayoutAnchorable")
        {
            if (DockView.Ins == null)
                return;
            if (typeOfLayout == "LayoutAnchorable")
            {

            }
            else if (typeOfLayout == "LayoutDocument")
            {
                try
                {
                    var layoutDocumentPaneGroup = DockView.Ins.dockManager.Layout
                        .Descendents()
                        .OfType<LayoutDocumentPaneGroup>()
                        .FirstOrDefault();
                    if (layoutDocumentPaneGroup != null)
                    {
                        LayoutDocumentPane layoutDocumentPane = new LayoutDocumentPane();
                        LayoutDocument item = new LayoutDocument();

                        if (contentId == "Vision")
                        {
                            item = MainViewModel.LayoutDocument_Vision;
                            if (layoutDocumentPaneGroup.Children.Count < 1)
                            {
                                layoutDocumentPaneGroup.Children.Add(new LayoutDocumentPane());
                            }
                            layoutDocumentPane = (LayoutDocumentPane)
                                layoutDocumentPaneGroup.Children[0];
                        }

                        if (isChecked)
                        {
                            if (!layoutDocumentPane.Children.Contains(item))
                            {
                                layoutDocumentPane.Children.Add(item);
                            }
                        }
                        else if (layoutDocumentPane.Children.Contains(item))
                        {
                            layoutDocumentPane.Children.Clear();
                        }
                    }
                }
                catch (Exception ex)
                {

                }
            }
        }

        public void OpenSolution(string fileName)
        {
            CurrentSolution = fileName;
            Solution.Ins = SerializeHelp.BinDeserialize<Solution>(fileName);
            Solution.Ins.LoadCommunacation();
            //if (Solution.Ins.QuickMode)
            //{
            //    MainView.Ins.btnQuickMode.Foreground = Brushes.Lime;
            //}
            //else
            //{
            //    MainView.Ins.btnQuickMode.Foreground = Brushes.LightGray;
            //}
            ToolView.Ins.UpdateTree();
            Solution.Ins.CurrentProject = Solution.Ins.GetProjectById(
                Solution.Ins.CurrentProjectID
            );
            ProcessView.Ins.UpdateTree();
        }

        /// <summary>
        /// 打开解决方案文件
        /// </summary>
        private async Task OpenSolutionAsync()
        {
            OpenFileDialog openFileDialog = new OpenFileDialog
            {
                Filter = "解决方案 (*.vm)|*.vm",
                DefaultExt = "vm"
            };

            if (openFileDialog.ShowDialog() == true)
            {
                var view = LoadingView.Ins;
                view.LoadingShow("加载项目中，请稍等...");

                // 停止当前项目
                if (Solution.Ins.CurrentProject != null && Solution.Ins.CurrentProject.RunMode != eRunMode.None)
                {
                    Solution.Ins.CurrentProject.Stop();
                }
                OpenSolution(openFileDialog.FileName);
                if (Solution.Ins.CurrentProject != null)
                {
                    foreach (var item in Solution.Ins.CurrentProject.ModuleList)
                    {
                        item.Loaded();
                    }
                }
                await Task.Delay(100); // 异步等待，避免阻塞 UI

                view.Close();
            }
        }

        /// <summary>
        /// 检查是否可以保存解决方案
        /// </summary>
        /// <returns>是否可以保存</returns>
        private bool CanSaveSolution()
        {
            foreach (var item in Solution.Ins.ProjectList)
            {
                if (item.GetThreadStatus())
                {
                    MessageView.Ins.MessageBoxShow("程序运行状态禁止保存工程！", eMsgType.Warn);
                    return false;
                }
            }
            return true;
        }

        /// <summary>
        /// 显示保存文件对话框
        /// </summary>
        /// <param name="title">对话框标题</param>
        /// <param name="defaultFileName">默认文件名</param>
        /// <param name="filter">文件过滤器</param>
        /// <returns>选定的文件路径</returns>
        private string? ShowSaveFileDialog(string title, string defaultFileName, string filter)
        {
            SaveFileDialog saveFileDialog = new SaveFileDialog
            {
                Title = title,
                FileName = defaultFileName,
                DefaultExt = Path.GetExtension(defaultFileName),
                Filter = filter
            };

            return saveFileDialog.ShowDialog() == true ? saveFileDialog.FileName : null;
        }

        #endregion
        #region HotKey
        public void RegisterHotKey()
        {
            IntPtr m_Hwnd = ((HwndSource)PresentationSource.FromVisual(mainView)).Handle;
            HwndSource hWndSource = HwndSource.FromHwnd(m_Hwnd);
            if (hWndSource != null)
            {
                hWndSource.AddHook(WndProc);
            }
            HotKeyHelper.RegisterHotKey(
                new HotKeyModel() { SelectType = EType.Ctrl, SelectKey = EKey.S },
                m_Hwnd,
                HotKeyManager.SaveTemplate_ID
            );
            HotKeyHelper.RegisterHotKey(
                new HotKeyModel() { SelectType = EType.Ctrl, SelectKey = EKey.O },
                m_Hwnd,
                HotKeyManager.OpenTemplate_ID
            );
            HotKeyHelper.RegisterHotKey(
                new HotKeyModel() { SelectType = EType.Ctrl, SelectKey = EKey.P },
                m_Hwnd,
                HotKeyManager.OpenDeviceParam_ID
            );
            HotKeyHelper.RegisterHotKey(
                new HotKeyModel() { SelectType = EType.None, SelectKey = EKey.F5 },
                m_Hwnd,
                HotKeyManager.ContinueRun_ID
            );
            HotKeyHelper.RegisterHotKey(
                new HotKeyModel() { SelectType = EType.None, SelectKey = EKey.F6 },
                m_Hwnd,
                HotKeyManager.StepRun_ID
            );
            HotKeyHelper.RegisterHotKey(
                new HotKeyModel() { SelectType = EType.None, SelectKey = EKey.F8 },
                m_Hwnd,
                HotKeyManager.ScreenCapture_ID
            );
            HotKeyHelper.RegisterHotKey(
                new HotKeyModel() { SelectType = EType.Ctrl, SelectKey = EKey.E },
                m_Hwnd,
                HotKeyManager.EditTemplate_ID
            );
            HotKeyHelper.RegisterHotKey(
                new HotKeyModel() { SelectType = EType.None, SelectKey = EKey.F9 },
                m_Hwnd,
                HotKeyManager.Help_ID
            );
            HotKeyHelper.RegisterHotKey(
                new HotKeyModel() { SelectType = EType.None, SelectKey = EKey.Escape },
                m_Hwnd,
                HotKeyManager.StopProcess_ID
            );
        }

        public void UnregisterHotKey()
        {
            IntPtr m_Hwnd = ((HwndSource)PresentationSource.FromVisual(mainView)).Handle;
            HotKeyHelper.UnregisterHotKey(m_Hwnd, HotKeyManager.SaveTemplate_ID);
            HotKeyHelper.UnregisterHotKey(m_Hwnd, HotKeyManager.OpenTemplate_ID);
            HotKeyHelper.UnregisterHotKey(m_Hwnd, HotKeyManager.OpenDeviceParam_ID);
            HotKeyHelper.UnregisterHotKey(m_Hwnd, HotKeyManager.ContinueRun_ID);
            HotKeyHelper.UnregisterHotKey(m_Hwnd, HotKeyManager.StepRun_ID);
            HotKeyHelper.UnregisterHotKey(m_Hwnd, HotKeyManager.ScreenCapture_ID);
            HotKeyHelper.UnregisterHotKey(m_Hwnd, HotKeyManager.EditTemplate_ID);
            HotKeyHelper.UnregisterHotKey(m_Hwnd, HotKeyManager.Help_ID);
            HotKeyHelper.UnregisterHotKey(m_Hwnd, HotKeyManager.StopProcess_ID);
        }

        private IntPtr WndProc(
        IntPtr hWnd,
        int msg,
        IntPtr wideParam,
        IntPtr longParam,
        ref bool handled)
        {
            switch (msg)
            {
                case HotKeyManager.WM_HOTKEY:
                    switch (wideParam.ToInt32())
                    {
                        case HotKeyManager.SaveTemplate_ID:
                            if (RightControl.Ins.Save)
                            {
                                NavOperateCommand.Execute("Save");
                            }
                            break;
                        case HotKeyManager.OpenTemplate_ID:
                            if (RightControl.Ins.Open)
                            {
                                NavOperateCommand.Execute("Open");
                            }
                            break;
                        case HotKeyManager.OpenDeviceParam_ID:
                            break;
                        case HotKeyManager.ContinueRun_ID:
                            Solution.Ins.CurrentProject.ContinueRunFlag = true;
                            Solution.Ins.CurrentProject.Breakpoint.Set();
                            break;
                        case HotKeyManager.StepRun_ID:
                            Solution.Ins.CurrentProject.Breakpoint.Set();
                            break;
                        case HotKeyManager.ScreenCapture_ID:
                            break;
                        case HotKeyManager.EditTemplate_ID:
                            break;
                        case HotKeyManager.Help_ID:
                            HelpDocumentCommand.Execute(1);
                            break;
                        case HotKeyManager.StopProcess_ID:
                            if (ProcessView.Ins.moduleTree.SelectedItem == null)
                                return IntPtr.Zero;
                            ModuleNode node = (
                                ProcessView.Ins.moduleTree.SelectedItem as ModuleNode
                            );
                            if (node == null)
                                return IntPtr.Zero;
                            Solution.Ins.CurrentProject.CloseModuleByName(node.DisplayName);
                            break;
                        default:
                            break;
                    }
                    handled = true;
                    break;
            }
            return IntPtr.Zero;
        }

        #endregion

    }
}
